package example;

import framework.Board;
import framework.State;
import framework.StateCalculator;

/**
 * This is the state calculator that returns the new state given the index of a
 * cell. Specifically, any live cell with fewer than two live neighbors dies, as
 * if caused by under-population. Any live cell with two or three live neighbors
 * lives on to the next generation. Any live cell with more than three live
 * neighbors dies, as if by overcrowding. Any dead cell with at least two live
 * neighbors becomes a live cell, as if by reproduction.
 * 
 * @author jtumarki, ntibrewa, shuaihan, wesleyk
 * 
 */
public class ConwayCalculator implements StateCalculator {

	/**
	 * @param currX x position
	 * @param currY y position
	 * @param b Board that next state and positions are relevant to
	 */
	@Override
	public State getNextState(int currX, int currY, Board b) {
		State currentState = b.getState(currX, currY);
		State tempState = null;
		int numAlive = 0;
		int xPos = currX, yPos = currY;

		/*
		 * get the states of all 8 neighbors and update the numAlive
		 */
		for (int i = -1; i < 2; i++) {
			for (int j = -1; j < 2; j++) {
				xPos = currX + i;
				yPos = currY + j;
				if (!(i == 0 && j == 0) && b.isValidPosition(xPos, yPos)) {
					tempState = b.getState(xPos, yPos);
					if (tempState instanceof AliveState) {
						numAlive += 1;
					}
				}
			}
		}

		/* only those with 2 or 3 live neighbors live */
		if (currentState instanceof AliveState) {
			if (numAlive == 2 || numAlive == 3)
				return new AliveState();
			return new DeadState();
		}

		/* only those with at least 2 live neighbors live */
		if (currentState instanceof DeadState) {
			if (numAlive >= 2)
				return new AliveState();
			return new DeadState();
		}

		/* every cell is either AliveState or DeadState */
		throw new IllegalArgumentException(
				"board should not contain unrecognized cells");
	}
}
